﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Lswweb.Domain.ResourceConfiguration;
using Lswweb.Common;

namespace Lswweb.Domain
{
    /// <summary>
    /// 需要进行重构，例如：Url,Map,Exception都应该使用接口，不应该进接和资源管理模块
    /// </summary>
    public partial class ResourceManagement
    {
        private string language;
        private ResourceUrls siteUrs;

        private ResourceManagement(string language,ResourceUrls siteUrls)
        {
            this.language = language;
            this.siteUrs = siteUrls;
        }

        public ResourceStrings Strings
        {
            get
            {
                return ResourceManagement.FindByCache<ResourceStrings>(
                    BuilderCacheKey("strings"),
                    new ResourceStrings(GetFilePath("Resources.xml")),
                    null);
            }
        }

        public ResourceStrings Settings
        {
            get 
            {
                return ResourceManagement.FindByCache<ResourceStrings>(
                    BuilderCacheKey("settings"),
                    new ResourceStrings(GetFilePath("Settings.config")),
                    null);
            }
        }

        public ResourceMessage ExceptionMessages
        {
            get 
            {
                return ResourceManagement.FindByCache<ResourceMessage>(
                    BuilderCacheKey("messages"),
                    new ResourceMessage(GetFilePath("Messages.xml")),
                    null);
            }
        }

        public ResourceMaps Maps
        {
            get
            {
                return ResourceManagement.FindByCache<ResourceMaps>(
                    BuilderCacheKey("maps"),
                    new ResourceMaps(GetFilePath("Maps.config"), Strings, this.siteUrs),
                    Strings,
                    this.siteUrs);
            }
        }

        private string BuilderCacheKey(string cacheKey)
        {
            return string.Format("{0}_{1}",this.language,cacheKey);
        }

        private string GetFilePath(string fileName)
        {
            string url = UrlHelper.ResolveUrl(string.Format("/Language/{0}/{1}", this.language, fileName));
            return ResourceManagement.serverUtility.MapPath(url);
        }
    }

    /// <summary>
    /// static部分
    /// </summary>
    public partial class ResourceManagement
    {
        #region 单例

        private static IDictionary<string, ResourceManagement> contents;

        /// <summary>
        /// 单例实例
        /// </summary>
        public static ResourceManagement Content
        {
            get
            {
                string language = SiteContext.Current.Language;

                if (!ResourceManagement.contents.ContainsKey(language))
                {
                    ResourceManagement.contents.Add(
                        language,
                        new ResourceManagement(language, ResourceManagement.UrlCollection));
                }

                return ResourceManagement.contents[language];
            }
        }

        #endregion



        private static ICacheManager cacheManager;
        private static HttpServerUtility serverUtility;

        /// <summary>
        /// 静态构造方法
        /// </summary>
        static ResourceManagement()
        {
            ResourceManagement.cacheManager = Globals.GetCacheManage;
            ResourceManagement.serverUtility = HttpContext.Current.Server;
            ResourceManagement.contents = new Dictionary<string, ResourceManagement>();
        }

        /// <summary>
        /// 语言集合
        /// </summary>
        public static ResourceLanguage LanguageCollection
        {
            get
            {
                return ResourceManagement.FindByCache<ResourceLanguage>(
                    "languages",
                    new ResourceLanguage(
                        ResourceManagement.serverUtility.MapPath(
                            UrlHelper.ResolveUrl("/Language/language.xml"))),
                    null);
            }
        }

        /// <summary>
        /// 网站url集合
        /// </summary>
        public static ResourceUrls UrlCollection
        {
            get
            {
                return ResourceManagement.FindByCache<ResourceUrls>(
                    "siteUrls",
                    new ResourceUrls(
                        ResourceManagement.serverUtility.MapPath(
                            UrlHelper.ResolveUrl("/Support/SiteUrls.config"))),
                    null);//ResourceManagement.Content.Maps会死循环，因为构造ResourceManagement需要先实例UrlCollection
            }
        }

        #region 静态方法 

        /// <summary>
        /// 从缓存中查询IResource，如果缓存中不存在则把对象加入缓存
        /// </summary>
        /// <typeparam name="T">查询返回类型</typeparam>
        /// <param name="cacheKey">缓存key</param>
        /// <param name="cacheValue">缓存对像</param>
        /// <param name="resourceExpiratons">缓存依赖对像</param>
        /// <returns>IResource</returns>
        private static T FindByCache<T>(string cacheKey, T cacheValue, params IResource[] resourceExpiratons)
            where T : IResource
        {
            if (!ResourceManagement.cacheManager.Contains(cacheKey))
            {
                IList<ICacheItemExpiration> cacheItems = new List<ICacheItemExpiration>();
                cacheItems.Add(new FileDependency(cacheValue.ResourceFilePath));
                resourceExpiratons.ForEach(info=>cacheItems.Add(new FileDependency(info.ResourceFilePath)));

                ResourceManagement.cacheManager.Add(
                    cacheKey,
                    cacheValue,
                    CacheItemPriority.High,
                    null,
                    cacheItems.ToArray());
            }

            return (T)ResourceManagement.cacheManager[cacheKey];
        }

        #endregion
    }
}
